#include <string>
#include<fstream>
#include<iostream>
#include<vector>

using namespace std;


class  kansu { public: string fncname; string reval; vector<string> hensu;  
string ren() {  
int m; string s;
for(m=0; m<(int)hensu.size()-1; m++) s += hensu[m]  + ", ";
s += hensu[m]; return s; }
//
string renban() {  
int m; string s; char ch[256]; 
for(m=0; m<(int)hensu.size()-1; m++) { 
sprintf(ch, " x%d, ", m); s += hensu[m]  + ch; }
sprintf(ch, " x%d", m);   s += hensu[m]  + ch;
return s; }
//
string nban() {  
int m; string s; char ch[256]; 
for(m=0; m<(int)hensu.size()-1; m++) { 
sprintf(ch, " x%d, ", m); s += ch; }
sprintf(ch, " x%d", m);   s += ch;
return s; }


};



kansu kansu_split( string s ) {
int m , n, k;
kansu x;
while(1){
m=s.find(" *"); 
if(m==-1) break;
for(n=m; n>=0; n--) if(s[n]!=' ')break;
s=s.substr(0, n+1) + "* " + s.substr(m+2); }
k=s.find("("); if(k==-1) return kansu();
for( m=k-1; s[m]==' ' ; m--); n=m; for( ; s[m]!=' ' ; m--); m++;
x.fncname = s.substr(m, n+1-m);
x.reval = s.substr(0, m);
n=k;
while(1){
for( m=n+1; s[m]==' ' ; m++); for( n=m+1; s[n]!=' ' ; n++);
x.hensu.push_back( s.substr(m, n+1-m) );
for( ; n<(int)s.size(); n++) if(s[n]==',') break;
if( n>=(int)s.size() ) break; }
return x; }



void conv( string fn ) {
int m,n;
string dllname; n=fn.find("."); if(n==-1) dllname=fn; else  dllname=fn.substr(0,n);
string old=dllname + "_old.h";
rename( &fn[0], &old[0] );


fstream fp(&old[0]);


int fileSize = (int) fp.seekg(0, std::ios::end).tellg();
fp.seekg(0, std::ios::beg);

string s(fileSize,'\0');
fp.read(&s[0], fileSize);
fp.close();


for(n=0; n<fileSize; n++) if(s[n]<32) s[n]=32;
m=0; vector<kansu> x;
for(n=0; n<fileSize; n++) if(s[n]==';') {
x.push_back( kansu_split( s.substr(m, n-m) ) );  
m=n+1; }

char ch[2048];
fstream fq(&fn[0] , ios::out);
fq<<"#include <stdio.h>"<<endl;
fq<<"#include <windows.h>"<<endl;
fq<<"#define FNCCALL __stdcall"<<endl;
fq<<"//#define FNCCALL __fastcall"<<endl;
fq<<"//#define FNCCALL _cdecl "<<endl;
sprintf(ch,"namespace %s { \nclass DLLload_%s {", &dllname[0], &dllname[0] );
fq<<ch<<endl;
fq<<"HINSTANCE hd;"<<endl;
//
for(n=0; n<(int)x.size(); n++) {
sprintf(ch, "%s (FNCCALL* _%s)( ", &(x[n].reval)[0], &(x[n].fncname)[0] );
fq<<ch<<x[n].ren()<<");\n"; }
//
for(n=0; n<(int)x.size(); n++) {
sprintf(ch, "friend %s %s( ", &(x[n].reval)[0], &(x[n].fncname)[0] );
fq<<ch<<x[n].ren()<<");\n"; }
fq<<"public:"<<endl;
sprintf(ch,
"DLLload_%s() {\n hd = LoadLibraryW(L\"%s.dll\");\n if(hd==NULL) { printf(\"%s.dll load err\\n\"); return; }"
, &dllname[0], &dllname[0], &dllname[0]);
fq<<ch<<endl;

for(n=0; n<(int)x.size(); n++) {
sprintf(ch, "_%s = (%s (FNCCALL*)(%s) ) GetProcAddress( hd, \"%s\" );" 
, x[n].fncname.c_str(), x[n].reval.c_str(), x[n].ren().c_str(), x[n].fncname.c_str() );
fq<<ch<<endl; }
sprintf(ch, "}} _DLLload_%s ;" , &dllname[0]);
fq<<ch<<endl;
//int  SetNkfOption(char *a) {  return _DLLload_nkf32._SetNkfOption(a); }

for(n=0; n<(int)x.size(); n++) {
sprintf(ch, "%s %s(%s) { return _DLLload_%s._%s(%s); }", 
x[n].reval.c_str(), x[n].fncname.c_str(),  x[n].renban().c_str(), 
&dllname[0], x[n].fncname.c_str(), x[n].nban().c_str() );
fq<<ch<<endl; }
fq<<"}"<<endl;
fq.close(); }




int main(){



conv("nkf32.h");
return 0;

}
